from Trigger import TriggerStatus
from Job import  Job, JobStatus, JobResult
    
class NodeJob():
    def __init__(self, top_job, mark):
        self.top_job = top_job
        self.job = None
        self.trigger = None
        self.mark = mark
    
    def status(self):
        return self.job.status
    
    def Result(self):
        return self.job.Result()
    
    def Status(self):
        return self.job.Status()
    
    def onJobStop(self, job):
        assert(job is self.job)
        if self.stop_handler:
            self.stop_handler(self)
    
    def setjob(self, job):
        assert(not(job is self.top_job))
        self.job = job
        self.job.stop_handler = self.onJobStop
        
    def setTrigger(self, trigger):
        self.trigger = trigger
        
    def onChange(self, mark, condition):
        if self.trigger.status == TriggerStatus.wait:
            self.trigger.onChange(mark, condition)
            if self.trigger.status == TriggerStatus.trigger:
                self.job.status = JobStatus.WaitingToRun
            elif self.trigger.status == TriggerStatus.invalid:
                self.job.canceled()
    
    def isComplete(self):
        return self.job.isCompletion()
    
class SequenceJob(Job):
    def __init__(self):
        self.job_list = {}

    
    def addJob(self, mark, job):
        if mark  in self.job_list:
            return False
        
        node_job = NodeJob(self, mark)
        node_job.setjob(job)
        self.job_list[mark] = node_job
        node_job.stop_handler = self.onSubJobComplete
        
        return True
            
    def removeJob(self, mark):
        if mark in self.job_list:
            self.job_list.pop(mark)
    
    def setTirgger(self, mark, tirgger):
        if mark not in self.job_list:
            return False
        
        
        depend_job = tirgger.dependJob()
        if mark in depend_job:
            return False
        
        self.job_list[mark].setTrigger(tirgger)
        
        
    def start(self):
        for v  in self.job_list.values():
            v.onChange('main', JobResult.Success)
        
    def onCancel(self):
        for v in self.job_list.values():
            v.job.onCancel(self)
        
    def onSubJobComplete(self, job):
        for v in self.job_list.values():
            if not v is job:
                v.onChange(job.mark, job.Result())
        
        all_finish = True
        for  v in self.job_list.values():
            if not v.isComplete():
                all_finish = False
                break
        
        if all_finish:
            self.status = JobStatus.RunToCompletion
            
        